Jelly Forest 入門 - Unity ゲームガイドでは、ソーシャルサインインやアップグレード、コスメティックアイテムなどのブロックチェーン機能を備え、これらのアイテムがすべてスマートコントラクトウォレットに保存される2Dランナーゲームを紹介します。
JellyForest
を少し調整することで、iOS と Android で動作するビルドを作成できました。
SequenceConfig
スクリプタブルオブジェクト(インストール時に Package Manager の Samples メニューからインポート)に、Builder で追加した Google および Apple のクライアントIDと、WaaSConfigKey
に設定キーを入力してください。
Settings > API Access Keys
の prod
キーに入力してください。Canvas
を作成し、Canvas Scaler
コンポーネントを追加して「Scale with Screen Size」UIスケールモードを使用します。これにより、LoginPanel や他の UI 要素がビルドターゲットを切り替えても自動的にスケーリングされます。LoginPanel
プレハブを Canvas の下にシーン階層へドラッグします。これは Project ウィンドウの Packages > Sequence Embedded Wallet SDK > SequenceFrontend > Prefabs
にあります。LoginPanel
の Open
を呼び出せるようにします。実装例はこちら:LoginPanel
プレハブとの参照を切り離し、シーンビューで自由に編集できるようにします。
LoginPanel
ゲームオブジェクトを選択します。LoginPanel
ゲームオブジェクトを右クリックします。Prefab > Unpack Completely
を選択します。LoginPage
や OpenIdAuthenticator
の実装を確認してみてください。
認証は Open ID Connect Implicit Flow を利用しています。
OpenIdAuthenticator.SignedIn
イベントが発火します。これにより SequenceLogin.ConnectToWaaS
で認可プロセスが始まります。
SequenceWallet.OnWalletCreated
イベントに購読する必要があります。
SequenceConnector
をインポートすることを強くおすすめします。初期コードが多数含まれており、SDK とのやりとりに便利なインターフェースとして機能します。JellyForest でもこのコードを多用しました。
JellyForest では、SequenceWallet.OnWalletCreated
イベントが発火した際に次のシーンを読み込む LevelLoader MonoBehaviour も作成しました。
git clone https://github.com/0xsequence-demos/cloudflare-worker-sequence-relayer.git
を実行し、続いて cd cloudflare-worker-sequence-relayer
git checkout permissionedMinter
pnpm install
で依存関係をインストールしますwrangler.toml
を開きます
name
の文字列を変更してサーバー名を設定しますPKEY
に設定します。CONTRACT_ADDRESS
を設定します。PROJECT_ACCESS_KEY
を設定します。これは、先ほどBuilder ConsoleでSequenceConfig
スクリプタブルオブジェクトをセットアップした際に取得した本番用APIキーです。CHAIN_HANDLE
を設定します。これが何かわからない場合は、Builder ConsoleのNode Gatewayページで各ネットワークのCHAIN_HANDLE
を確認できます。pnpm dev
- これでサーバーがローカルにデプロイされます。どのlocalhostでデプロイされたかはコマンドラインに表示されます。curl http://localhost:8787
- 表示されたlocalhostに置き換えてください。これでサーバーにリクエストを送ります。Contracts
から該当するコントラクトを探し、クリックして開きます。Write Contract
をクリックします。grantRole
を展開します。role
には0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6
を入力します。これはMINTER_ROLE
のKeccak-256ハッシュ値です。account
にはミンターのウォレットアドレスを貼り付けます。wrangler deploy
- これでCloudflare Workerにコードがデプロイされ、ミント用のURLが発行されます。proof
はミントリクエストを送るクライアント側で生成されます。Unity SDKでは、MintingRequestProverによって実装されています。
PermissionedMinter.MintToken
メソッドを呼び出すことで、パーミッション付きミンターにリクエストを送信できます。
Jelly Forestでは、プレイヤーがレベルを進むごとに多くのコインを集めます。これらはすべてERC1155トークンです。プレイヤーに快適なUXを提供するために、まだ解決すべき課題がいくつかあります。
SequenceWallet
を受け取った際、SequenceConnector(ゲーム内でSequence SDKとやり取りする主なインターフェース)がInventory
を作成します。
Inventory
は、ゲーム内でシンプルなキャッシュとして使われます。作成時や必要に応じて、Indexerを使ってユーザーのウォレット内トークンを取得します。その後、ユーザーがトークンを獲得するたびにキャッシュ(Inventory
)とオンチェーンデータを更新します。
Inventory
の全実装はこちらでご覧いただけます
SequenceConnector
のGameObjectにアタッチし、Awakeで参照を取得しています。
Inventory
が更新され、ミントトランザクションがPermissionedMinterTransactionQueuer
のキューに追加されます。PermissionedMinterTransactionQueuer
は、可能な限りトランザクションを自動的にまとめて、ガス代を最小限に抑えます。
Jelly Forestでは、プレイヤーがゲームオーバーになるたび、ただし、30秒未満の間隔では送信されないように設定しています。
TransactionQueuers
は、X秒ごとに自動で送信、関数呼び出しで促されたときに送信(ただしY秒未満では送信しない)、または促されたときに最小間隔(Y秒)を無視して即時送信、など柔軟に設定できます。
トランザクションキューアの設定を決める際に考慮すべきポイントをいくつか挙げます:
data
パラメータでミントしたいトークンIDを指定すると、コントラクトは各トークンIDの必要数を受け取ったかどうかを確認します。条件を満たしていれば、コントラクトはトークンをバーンし、指定されたトークンIDを送信者(ユーザー)にミントします。条件を満たさない場合は、トランザクションが失敗し、ロールバックされます。
このコントラクトには、Builder Consoleでゲームコントラクトのミント権限を付与しています。
Contracts
から該当するコントラクトを探し、クリックして開きます。Write Contract
をクリックします。grantRole
を展開します。role
には0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6
を入力します。これはMINTER_ROLE
のKeccak-256ハッシュ値です。account
にはミンターのウォレットアドレスを貼り付けます。BurnToMint
スマートコントラクトは、第三者による監査を受けていません。再利用する際はご注意ください!
:::
ユーザーがショップでアップグレードやコスメティックアイテムを購入すると、PurchaseShopItemQueueableTransactionをSequenceConnector
内のSequenceWalletTransactionQueuerに追加し、BurnToMint
スマートコントラクトへトランザクションを送信します。
BurnToMint
コントラクトで定義したミント要件を同期させるのは手間がかかり、バグの原因にもなりやすいことが分かりました。
そこで、ShopItem
のScriptable Object用にエディタ拡張を作成し、ボタンを追加しました。このボタンを押すと、オンチェーンで定義されているミント要件とScriptable Objectの内容が一致しているかを確認し、異なっていればScriptable Objectに合わせてBurnToMint
コントラクトのミント要件を更新するトランザクションを送信します。トランザクションは、開発者のマシンに環境変数として保存された秘密鍵から作成されたEOAウォレットを使って送信されます。このEOAウォレットは、このコントラクトのオーナーです。
実際、ショップページは60秒ごと(およびページを開くたび)にスマートコントラクトへミント要件の変更を問い合わせ、UIを自動で更新しています。これにより、ゲームの経済バランスをアップデートなしでリアルタイムに調整できます!
下の動画をクリックしてください
Item
にPowerUpType
とティアを割り当てています。そして、プレイヤーが所有する各タイプの最強パワーアップをInventory
から検索する仕組みを作っています。